package com.arpa.oms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.IterUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.arpa.ntocc.common.common.cache.AreaCache;
import com.arpa.ntocc.common.common.cache.PartyCache;
import com.arpa.ntocc.common.common.exception.ServiceException;
import com.arpa.ntocc.common.common.util.CommonUtil;
import com.arpa.ntocc.common.common.util.UserUtil;
import com.arpa.ntocc.common.domain.enums.CustomerCheckStatusEnum;
import com.arpa.oms.domain.dto.OmsSupplierDTO;
import com.arpa.oms.domain.dto.OmsSupplierFormDTO;
import com.arpa.oms.domain.entity.OmsSupplier;
import com.arpa.oms.domain.vo.OmsSupplierVO;
import com.arpa.oms.mapper.OmsSupplierMapper;
import com.arpa.oms.service.IOmsSupplierService;
import com.arpa.wms.cache.SupplierCache;
import com.arpa.wms.domain.consts.NumConst;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import static com.arpa.wms.domain.consts.TipConst.SUPPLIER_CODE_EXIST;
import static com.arpa.wms.domain.consts.TipConst.SUPPLIER_NAME_EXIST;

/**
 * <p>
 * 供应商 服务实现类
 * </p>
 *
 * @author wangdong
 * @since 2021-07-21
 */
@Service
public class OmsSupplierServiceImpl extends ServiceImpl<OmsSupplierMapper, OmsSupplier> implements IOmsSupplierService {


    private final SupplierCache supplierCache;


    private final PartyCache partyCache;

    private final AreaCache areaCache;


    public OmsSupplierServiceImpl(SupplierCache supplierCache, PartyCache partyCache, AreaCache areaCache ) {
        this.supplierCache = supplierCache;
        this.partyCache = partyCache;
        this.areaCache = areaCache;
    }




    /**
     * 保存
     *
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean save(OmsSupplierFormDTO dto) {
        OmsSupplier entity = new OmsSupplier();
        BeanUtil.copyProperties(dto,entity );
        int count = baseMapper.selectCount(new QueryWrapper<OmsSupplier>().lambda().eq(OmsSupplier::getSupplierCode, entity.getSupplierCode()));
        if (count > 0) {
            throw new ServiceException(SUPPLIER_CODE_EXIST);
        }
        count = baseMapper.selectCount(new QueryWrapper<OmsSupplier>().lambda().eq(OmsSupplier::getName, entity.getName()));
        if (count > 0) {
            throw new ServiceException(SUPPLIER_NAME_EXIST);
        }
        List<String> areaList = dto.getAreaList();
        if (IterUtil.isNotEmpty(areaList)&&areaList.size()==4) {
            entity.setCountry(areaList.get(0));
            entity.setProvince(areaList.get(1));
            entity.setCity(areaList.get(2));
            entity.setCounty(areaList.get(3));
        }
        entity.setStatus(0);
        entity.setCode(IdUtil.fastSimpleUUID());
        entity.setCreatedBy(UserUtil.getCode());
        entity.setModifiedBy(UserUtil.getCode());
        entity.setModifiedName(partyCache.translate(UserUtil.getCode()));
        entity.setCreatedName(partyCache.translate(UserUtil.getCode()));
        entity.setGroupCode(UserUtil.getBranchCode());
        supplierCache.flushAllCacheByGroupCode(UserUtil.getBranchCode());
        return super.save(entity);
    }


    /**
     * 根据code更新实体
     *
     * @param entity
     * @return
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public int updateByCode(OmsSupplierFormDTO entity) {
        OmsSupplier supplier = baseMapper.selectOne(new QueryWrapper<OmsSupplier>().lambda().eq(OmsSupplier::getCode, entity.getCode()));
        Optional.ofNullable(supplier).orElseThrow(() -> new ServiceException("查不到供应商信息"));


        CopyOptions copyOptions = new CopyOptions();
        copyOptions.setIgnoreNullValue(true);
        BeanUtil.copyProperties(entity,supplier,copyOptions);



        List<String> areaList = entity.getAreaList();
        if (IterUtil.isNotEmpty(areaList)&&areaList.size()==4) {
            supplier.setCountry(areaList.get(0));
            supplier.setProvince(areaList.get(1));
            supplier.setCity(areaList.get(2));
            supplier.setCounty(areaList.get(3));
        }
        supplier.setModifiedBy(UserUtil.getCode());
        supplier.setModifiedName(partyCache.translate(UserUtil.getCode()));
        supplierCache.flushCache(entity.getCode());

        if(supplier.getStatus()==2){
            supplier.setStatus(0);
        }
        return baseMapper.update(supplier, new QueryWrapper<OmsSupplier>().lambda().eq(OmsSupplier::getCode, entity.getCode()));
    }


    /**
     * 查询列表
     *
     * @param supplierDTO
     * @return
     */
    @Override
    public List<OmsSupplierVO> queryList(OmsSupplierDTO supplierDTO) {
        //排序字段名需要驼峰转数据库下划线类型字段名
        if (StringUtils.isNotEmpty(supplierDTO.getSortField())) {
            supplierDTO.setSortField(CommonUtil.camel2Underline(supplierDTO.getSortField()));
        }
        List<OmsSupplierVO> supplierVOList = baseMapper.queryList(supplierDTO);

        supplierVOList.forEach(e->{
            CustomerCheckStatusEnum enumByCode = CustomerCheckStatusEnum.getEnumByCode(e.getStatus());
            if (null != enumByCode) {
                e.setStatusText(enumByCode.getDesc());
            }
        });

        return supplierVOList;
    }

    @Override
    public List<OmsSupplierVO> queryByNameOrCode(OmsSupplierDTO supplierDTO) {
        return baseMapper.queryByNameOrCode(supplierDTO);
    }

    /**
     * 查询合计,包含总数
     *
     * @param supplierDTO
     * @return
     */
    @Override
    public OmsSupplierVO queryListSum(OmsSupplierDTO supplierDTO) {
        OmsSupplierVO supplierVO = baseMapper.queryListSum(supplierDTO);
        return supplierVO;
    }

    @Override
    public int batchDelete(List<String> codes, String modifiedBy) {
        codes.forEach(supplierCache::flushCache);
        return baseMapper.batchDelete(codes, modifiedBy);
    }

    /**
     * 模糊查询供应商
     *
     * @param keywords 关键字
     * @return
     */
    @Override
    public List<Map<String, Object>> search(String keywords) {

        List<Map<String, Object>> suppliers = supplierCache.getAllByGroupCode(UserUtil.getBranchCode());
        if (IterUtil.isNotEmpty(suppliers)) {
            // 过滤时，通过关键字，并且是已审核通过的
            if (StrUtil.isNotBlank(keywords)) {
                suppliers = suppliers.stream().filter(r -> NumConst.NUM_ONE.equals(r.get("status"))&&((StringUtils.containsAny(MapUtil.getStr(r, "name"), keywords)
                        || StringUtils.containsAny(MapUtil.getStr(r, "supplierCode"), keywords)
                        || StringUtils.containsAny(MapUtil.getStr(r, "phone"), keywords)))
                ).collect(Collectors.toList());
            } else {
                suppliers = suppliers.stream().filter(r -> NumConst.NUM_ONE.equals(r.get("status"))).collect(Collectors.toList());
            }
        }
        return suppliers;
    }

    @Override
    public OmsSupplierVO getOneInfo(String code) {
        OmsSupplier entity = baseMapper.selectOne(new QueryWrapper<OmsSupplier>().lambda().eq(OmsSupplier::getCode,code));
        Optional.ofNullable(entity).orElseThrow(() -> new ServiceException("没有查询到信息"));
        OmsSupplierVO supplierVO = new OmsSupplierVO();
        BeanUtil.copyProperties(entity, supplierVO);
        List<String> areaList = new ArrayList<>();
        areaList.add(entity.getCountry());
        areaList.add(entity.getProvince());
        areaList.add(entity.getCity());
        areaList.add(entity.getCounty());
        String areaStr = "";
        if (StrUtil.isNotBlank(entity.getCountry())) {
            areaStr = areaCache.translateCountry(entity.getCountry());
        }

        if (StrUtil.isNotBlank(entity.getProvince())) {
            if (StrUtil.isNotBlank(areaStr)) {
                areaStr = areaStr + "/" + areaCache.translateProvince(entity.getProvince());
            } else {
                areaStr = areaCache.translateProvince(entity.getProvince());
            }
        }
        if (StrUtil.isNotBlank(entity.getCity())) {
            if (StrUtil.isNotBlank(areaStr)) {
                areaStr = areaStr + "/" + areaCache.translateCity(entity.getCity());
            } else {
                areaStr = areaCache.translateCity(entity.getCity());
            }
        }
        if (StrUtil.isNotBlank(entity.getCounty())) {
            if (StrUtil.isNotBlank(areaStr)) {
                areaStr = areaStr + "/" + areaCache.translateCounty(entity.getCounty());
            } else {
                areaStr = areaCache.translateCounty(entity.getCounty());
            }
        }
        supplierVO.setArea(areaStr);


        supplierVO.setAreaList(areaList);
        return supplierVO;
    }


}
